package com.cnap.multiclouldmgmt.service.impl;

import com.cnap.multiclouldmgmt.model.AlgScheduleInfoV2Model;
import com.cnap.multiclouldmgmt.model.alg.AccountNameReqModel;
import com.cnap.multiclouldmgmt.model.enums.CloudVendorsEnum;
import com.cnap.multiclouldmgmt.model.enums.K8sRoleEnum;
import com.cnap.multiclouldmgmt.model.enums.K8sStatusEnum;
import com.cnap.multiclouldmgmt.model.enums.NetCostTypeEnum;
import com.cnap.multiclouldmgmt.model.gpu.GpuClusterMonitorInfo;
import com.cnap.multiclouldmgmt.model.k8sModels.*;
import com.cnap.multiclouldmgmt.model.k8sMonitorModels.*;
import com.cnap.multiclouldmgmt.model.vm.VmModel;
import com.cnap.multiclouldmgmt.repository.master.FlavorInfoMapper;
import com.cnap.multiclouldmgmt.repository.master.K8sClusterInfoMapper;
import com.cnap.multiclouldmgmt.repository.master.MicroSvcUseInfoMapper;
import com.cnap.multiclouldmgmt.service.AlgInfoService;
import com.cnap.multiclouldmgmt.service.K8sClusterService;
import com.cnap.multiclouldmgmt.service.MultiCloudMgmtService;
import com.cnap.multiclouldmgmt.service.PrometheusService;
import com.cnap.multiclouldmgmt.util.CnapCloudMgmtConstants;
import com.cnap.multiclouldmgmt.util.QuantityUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service("AlgInfoServiceImpl")
public class AlgInfoServiceImpl implements AlgInfoService {

    private final static Logger LOGGER = LoggerFactory.getLogger(AlgInfoServiceImpl.class);

    @Autowired
    private MultiCloudMgmtService multiCloudMgmtService;

    @Autowired
    private K8sClusterService k8sClusterService;

    @Autowired
    private PrometheusService prometheusService;

    @Autowired
    private FlavorInfoMapper flavorInfoMapper;
    @Autowired
    private MicroSvcUseInfoMapper microSvcUseInfoMapper;

    @Autowired
    private K8sClusterInfoMapper k8sClusterInfoMapper;

    /**
     *{
     *     "operation": "deploy",
     *     "policy": "load balancing",     //表示请求负载均衡的部署算法
     *     "parameters":
     *      {
     *        "cluster_state":{ //每个集群当前的状态，Dict格式，key为集群名称，value为具体资源值
     *          "cluster_name1":
     *            [//此处为list格式，每个节点占用资源情况为一个元素
     *                 {
     *                   "cpu_usage": [0.8,4.0], //CPU使用状况, [该节点当前cpu使用量,该节点cpu总量]，单位为核数
     *                   "memory_usage": [120,12288], //内存使用状况,[该节点当前内存使用量,总量]，单位为MB
     *                   "disk_throughput": [100, 1000], //磁盘吞吐量,[该节点当前占用读写速率，该节点磁盘总读写速率]，单位为MB/s
     *                   "disk_iops": [1200, 15000], //磁盘IOPS，[该节点当前占用读写次数，该节点磁盘秒均总读写次数]，单位次/s
     *                   "net_bandwidth": [1000,100000], //网络带宽，[该节点当前占用带宽，该节点网络总带宽]，单位bps
     *                   "delay":5, //节点网络时延
     *                   "loss_rate":0.05, //节点丢包率
     *                 },
     *                 {...},
     *           ],
     *          "cluster_name2":{
     *            ...//同上
     *          }
     *         },
     *         "deploy_num": 1, //部署集群数量，当前设定为1，算法已设置缺省，值为1时可不传入
     *         "replica_num":1, //部署副本数量，当前设定为1，算法已设置缺省，值为1时可不传入
     *
     *         "service_resources_map": //该部署的微服务的副本--消耗资源映射关系基准值
     *           {
     *               "cpu_usage": 0.3, //CPU使用状况, 每副本cpu使用量，单位为核数
     *               "memory_usage": 120, //内存使用状况,每副本内存使用量,单位为MB
     *               "disk_throughput": 50, //磁盘吞吐量,每副本占用读写速率，单位为MB/s
     *               "disk_iops": 200, //磁盘IOPS，每副本占用读写次数，单位次/s
     *               "net_bandwidth": 100, //网络带宽，每副本占用带宽，单位bps
     *            },
     *        "required_indictor_upperlimit": //该部署的微服务的需求指标(上限)
     *           {
     *                 "delay": 5,
     *                 "loss_rate": 0.05
     *             },//如果有就写，没有就空，比如时延会给一个上限值，丢包率有上限值
     *        "required_indictor_lowerlimit": //该部署的微服务的需求指标(下限)
     *           {//如果有就写，没有就空，比如吞吐率会有下限值
     *           }
     *      }
     * }
     * @param algReqModel
     * @return
     * @throws Exception
     */
    @Override
    public List<DynamicExpansionSvcAlgModel> getDynamicExpansionAlgInfo(AlgReqModel algReqModel) throws Exception {


        List<DynamicExpansionSvcAlgModel> result = new ArrayList<>();

        List<K8sClusterAlgInfoModel> k8sClusterAlgInfoModels = getHpaAlgInfo(algReqModel);
        Map<String,K8sClusterAlgInfoModel> k8sClusterAlgInfoModelMap = new HashMap<>();
        for (K8sClusterAlgInfoModel k8sClusterAlgInfoModel:k8sClusterAlgInfoModels){
            k8sClusterAlgInfoModelMap.put(k8sClusterAlgInfoModel.getK8sClusterName(),k8sClusterAlgInfoModel);
        }

        for (String k8sClusterName:algReqModel.getK8sClusterNames()){

            K8sClusterBasicModel k8sClusterBasicModel =
                    multiCloudMgmtService.getK8sClusterInfoByName(k8sClusterName);

            SvcModel svcModel =
                    k8sClusterService.getSvcInfo(k8sClusterBasicModel,algReqModel.getNamespace(),
                                                        algReqModel.getSvcName());
            if (svcModel == null){
                continue;
            }

            K8sClusterAlgInfoModel k8sClusterAlgInfoModel
                    = k8sClusterAlgInfoModelMap.get(k8sClusterName);

            DynamicExpansionSvcAlgModel dynamicExpansionSvcAlgModel = new DynamicExpansionSvcAlgModel();
            dynamicExpansionSvcAlgModel.setK8sClusterName(k8sClusterAlgInfoModel.getK8sClusterName());
            dynamicExpansionSvcAlgModel.setZoneId(k8sClusterAlgInfoModel.getZoneId());
            dynamicExpansionSvcAlgModel.setRegionId(k8sClusterAlgInfoModel.getRegionId());
            dynamicExpansionSvcAlgModel.setSvcName(algReqModel.getSvcName());

            //获取所有pod
            List<PodModel> podModels =
                    k8sClusterService.getAllPodsInfo(k8sClusterBasicModel,algReqModel.getNamespace());
            //获取svc用到的所有pod，
            long cpuUse = 0L;
            long cpuLimit = 0L;
            long memUse = 0L;
            long memLimit = 0L;
            for (PodModel podModel:podModels){

                if ((podModel.getPodLabelMap() == null)
                        ||(podModel.getPodLabelMap().isEmpty())){
                    continue;
                }

                for (String key:svcModel.getSeclectorMap().keySet()){

                    if ((podModel.getPodLabelMap().containsKey(key))
                            &&(StringUtils.equals(svcModel.getSeclectorMap().get(key),
                                                    podModel.getPodLabelMap().get(key)))){
                        cpuUse += podModel.getCpuUseByN();
                        cpuLimit += podModel.getPodLimitCpuByN();
                        memUse += podModel.getMemUseByKi();
                        memLimit += podModel.getPodLimitMemByKi();
                    }
                }
            }

            if (cpuLimit == 0L){
                dynamicExpansionSvcAlgModel.setSvcCpuLimit(k8sClusterAlgInfoModel.getClusterCpuNum() - k8sClusterAlgInfoModel.getClusterCpuUseNum() + QuantityUtils.changeCpuNtoNumDouble(cpuUse));
            }else {
                dynamicExpansionSvcAlgModel.setSvcCpuLimit(QuantityUtils.changeCpuNtoNumDouble(cpuLimit));
            }
            dynamicExpansionSvcAlgModel.setSvcCpuUse(QuantityUtils.changeCpuNtoNumDouble(cpuUse));

            if(memLimit == 0L){

                dynamicExpansionSvcAlgModel.setSvcMemLimit(k8sClusterAlgInfoModel.getClusterMemQuotaByMb() - k8sClusterAlgInfoModel.getClusterMemUseByMb() + QuantityUtils.changeMemKitoMiNoMi(memUse));
            }else {
                dynamicExpansionSvcAlgModel.setSvcMemLimit(
                        QuantityUtils.changeMemKitoMiNoMi(memLimit));
            }
            dynamicExpansionSvcAlgModel.setSvcMemUse(QuantityUtils.changeMemKitoMiNoMi(memUse));

            dynamicExpansionSvcAlgModel.setClusterMemUseByMb(k8sClusterAlgInfoModel.getClusterMemUseByMb());
            dynamicExpansionSvcAlgModel.setClusterMemQuotaByMb(k8sClusterAlgInfoModel.getClusterMemQuotaByMb());
            dynamicExpansionSvcAlgModel.setClusterCpuNum(k8sClusterAlgInfoModel.getClusterCpuNum());
            dynamicExpansionSvcAlgModel.setClusterCpuUseNum(k8sClusterAlgInfoModel.getClusterCpuUseNum());
            
            result.add(dynamicExpansionSvcAlgModel);
        }

        return result;
    }

    /**
     *{
     *    //部署完全失败，所有集群都不可用示例
     *     "msg": "fail deployment, no capable cluster for deployment",
     *     "code": 500,
     *     "require_resources": [ //list，此处返回推荐新增资源需求，缺几个集群则返回几个
     *         {//对于有些集群可以部署部分副本的，返回该集群名，及需要新增副本数的资源
     *             "cluster_name": "cluster_name1",
     *             "replica_num": 1
     *         },
     *         { //对于所有副本都无法部署的情况，不返回集群名，返回所有需要的副本数量
     *             "cluster_name": null,
     *             "replica_num": 2
     *         },
     *         {
     *             "cluster_name": null,
     *             "replica_num": 2
     *         }
     *     ],
     *     "target_cluster": []  //完全失败，没有可以部署的集群
     * }
     *
     *
     *
     * {
     *    //部署部分失败，部分集群都不可用示例
     *     "msg": "incomplete deployment, not enough require resources",
     *     "code": 300,
     *     "require_resources": [ //同上
     *         {
     *             "cluster_name": null,
     *             "replica_num": 2
     *         },
     *         {
     *             "cluster_name": null,
     *             "replica_num": 2
     *         }
     *     ],
     *     "target_cluster": [//部分失败，仍有可以部署的集群，但是数量小于请求部署的集群数量
     *         "cluster_name1"
     *     ]
     * }
     *
     *
     * { //部署完全成功示例
     *     "msg": "successful deployment",
     *     "code": 200,
     *     "require_resources": [],
     *     "target_cluster": [ //完全成功，返回请求中要求的集群数量的集群名
     *         "cluster_name2",
     *         "cluster_name1"
     *     ]
     * }
     * @param algReqModel
     * @return
     * @throws Exception
     */
    @Override
    public List<K8sClusterCostAlgInfoModel> getCostAlgInfo(AlgReqModel algReqModel) throws Exception {

        List<K8sClusterCostAlgInfoModel> result = new ArrayList<>();

        List<K8sClusterAlgInfoModel> k8sClusterAlgInfoModels = getHpaAlgInfo(algReqModel);
        for (K8sClusterAlgInfoModel k8sClusterAlgInfoModel : k8sClusterAlgInfoModels) {

            K8sClusterCostAlgInfoModel k8sClusterCostAlgInfoModel = new K8sClusterCostAlgInfoModel();
            k8sClusterCostAlgInfoModel.setK8sClusterName(k8sClusterAlgInfoModel.getK8sClusterName());
            k8sClusterCostAlgInfoModel.setZoneId(k8sClusterAlgInfoModel.getZoneId());
            k8sClusterCostAlgInfoModel.setRegionId(k8sClusterAlgInfoModel.getRegionId());
            k8sClusterCostAlgInfoModel.setNodeNum(k8sClusterAlgInfoModel.getNodeNum());
            k8sClusterCostAlgInfoModel.setCloudType(k8sClusterAlgInfoModel.getCloudType());
            k8sClusterCostAlgInfoModel.setCloudVendor(k8sClusterAlgInfoModel.getCloudVendor());
            k8sClusterCostAlgInfoModel.setCpuNodeNum(k8sClusterCostAlgInfoModel.getNodeNum());
            k8sClusterCostAlgInfoModel.setFpgaNodeNum(0);
            k8sClusterCostAlgInfoModel.setGpuNodeNum(0);

            //cpuNum
            int cpuNum = k8sClusterAlgInfoModel.getClusterCpuNum();
            k8sClusterCostAlgInfoModel.setPricePerCpuWorker(
                    Double.parseDouble(k8sClusterAlgInfoModel.getCpuCost())/cpuNum);
            k8sClusterCostAlgInfoModel.setPricePerFpgaWorker(0);
            k8sClusterCostAlgInfoModel.setPricePerGpuWorker(0);

            //换算成每小时的价格
            k8sClusterCostAlgInfoModel.setPricePerBs(
                    Double.parseDouble(k8sClusterAlgInfoModel.getDiskCost())/(30*24));

            k8sClusterCostAlgInfoModel.setPricePerFs(
                    Double.parseDouble(k8sClusterAlgInfoModel.getFileCost()));

            k8sClusterCostAlgInfoModel.setPriceModelNr(
                    NetCostTypeEnum.getDescribeByChineseDescribe(k8sClusterAlgInfoModel.getNetCostType()));
            k8sClusterCostAlgInfoModel.setPricePerNr(
                    Double.parseDouble(k8sClusterAlgInfoModel.getNetCost()));

            k8sClusterCostAlgInfoModel.setResidualCpuNum(
                    (double) k8sClusterAlgInfoModel.getClusterCpuNum() - k8sClusterAlgInfoModel.getClusterCpuUseNum());
            k8sClusterCostAlgInfoModel.setResidualRam(
                    (double)k8sClusterAlgInfoModel.getClusterMemQuotaByMb()
                            - (double)k8sClusterAlgInfoModel.getClusterMemUseByMb());
            k8sClusterCostAlgInfoModel.setResidualFpga(0);
            k8sClusterCostAlgInfoModel.setResidualFpga(0);
            k8sClusterCostAlgInfoModel.setResidualBs(
                    (double) k8sClusterAlgInfoModel.getClusterDiskQuotaByGb()
                            - (double)k8sClusterAlgInfoModel.getClusterDiskUseByGb());
            k8sClusterCostAlgInfoModel.setResidualFs(Integer.MAX_VALUE/2);

            List<NodeCostAlgInfoModel> nodeCostAlgInfoModels = new ArrayList<>();
            k8sClusterCostAlgInfoModel.setNodeCostAlgInfoModels(nodeCostAlgInfoModels);

            for(NodeModel nodeModel : k8sClusterAlgInfoModel.getNodeModels()) {

                if (StringUtils.isNotEmpty(algReqModel.getNodeAppType())){
                    if (!StringUtils.equals(nodeModel.getNodeLabelMap().get(
                            CnapCloudMgmtConstants.NODE_APP_TYPE_LABEL+algReqModel.getNodeAppType().toLowerCase()),
                            algReqModel.getNodeAppType())){
                        continue;
                    }
                }

                NodeCostAlgInfoModel nodeCostAlgInfoModel = new NodeCostAlgInfoModel();
                nodeCostAlgInfoModel.setNodeName(nodeModel.getNodeName());
                nodeCostAlgInfoModel.setNodeType("CPU Type");
                nodeCostAlgInfoModel.setNodeCpu(
                        QuantityUtils.changeCpuNtoNumDouble(nodeModel.getNodeCpuQuotaByN() - nodeModel.getNodeCpuUseByN())
                );
                nodeCostAlgInfoModel.setNodeRam(
                        QuantityUtils.changeMemKitoMiDouble(nodeModel.getNodeMemQuotaByKi() - nodeModel.getNodeMemUseNumByKi()));
                nodeCostAlgInfoModel.setNodeBsSize(nodeModel.getNodeDiskQuota() - nodeModel.getNodeDiskUseNum());
                nodeCostAlgInfoModel.setNodeBsIops(1000);
                nodeCostAlgInfoModel.setNodeBsHc(1000);
                nodeCostAlgInfoModel.setRegionId(k8sClusterCostAlgInfoModel.getRegionId());
                nodeCostAlgInfoModel.setZoneId(k8sClusterCostAlgInfoModel.getZoneId());
                nodeCostAlgInfoModel.setCloudVendor(k8sClusterCostAlgInfoModel.getCloudVendor());
                nodeCostAlgInfoModel.setCloudType(k8sClusterCostAlgInfoModel.getCloudType());
                nodeCostAlgInfoModels.add(nodeCostAlgInfoModel);
            }

            result.add(k8sClusterCostAlgInfoModel);


        }


        return result;
    }

    @Override
    public List<AlgScheduleInfoV2Model> getScheduleAlgInfoV2(AlgReqModel algReqModel) throws Exception {

        List<AlgScheduleInfoV2Model> algScheduleInfoV2Models = new ArrayList<>();

        for (String k8sClusterName : algReqModel.getK8sClusterNames()) {

            K8sClusterBasicModel k8sClusterBasicModel
                    = multiCloudMgmtService.getK8sClusterInfoByName(k8sClusterName);
            List<NodeModel> nodeModels = k8sClusterService.getAllNodeInfo(k8sClusterBasicModel);

            AlgScheduleInfoV2Model algClusterInfoV2Model = new AlgScheduleInfoV2Model();

            algClusterInfoV2Model.setK8sClusterName(k8sClusterBasicModel.getK8sClusterName());
            algClusterInfoV2Model.setRegionId(k8sClusterBasicModel.getRegionId());
            algClusterInfoV2Model.setZoneId(k8sClusterBasicModel.getZoneId());
            algClusterInfoV2Model.setCloudType(
                    CloudVendorsEnum.getCloudeTypeByDescribe(k8sClusterBasicModel.getCloudVendor()));

            //组成一个flavorId的map用于查找价格
            Map<String,String> flavorMap = new HashMap<>();
            for (VmModel vmModel:k8sClusterBasicModel.getVmModels()){

                flavorMap.put(vmModel.getInnerIp(),vmModel.getFlavorId());
            }

            Double cpuUse = 0d;
            Double cpuTotal = 0d;
            Double memUse = 0d;
            Double memTotal = 0d;
            int diskThrouthputNow = 0;
            int diskThrouthputTotal = 0;
            int diskIopsNow = 0;
            int diskIopsTotal = 0;
            Double price = 0d;
            boolean addFlag = false;
            for (NodeModel nodeModel:nodeModels){

                //找到部署这个微服务的所有node
                if (StringUtils.equals(nodeModel.getNodeLabelMap().get(CnapCloudMgmtConstants.NODE_APP_LABEL),
                        algReqModel.getSvcName())){
                    addFlag = true;
                    cpuUse +=
                            Double.parseDouble(QuantityUtils.changeCpuNtoNumStr(nodeModel.getNodeCpuUseByN()));
                    cpuTotal +=
                            Double.parseDouble(QuantityUtils.changeCpuNtoNumStr(nodeModel.getNodeCpuQuotaByN()));
                    memUse +=
                            Double.parseDouble(QuantityUtils.changeMemKiToGiStr(nodeModel.getNodeMemUseNumByKi()));
                    memTotal +=
                            Double.parseDouble(QuantityUtils.changeMemKiToGiStr(nodeModel.getNodeMemQuotaByKi()));
                    diskThrouthputNow +=
                            nodeModel.getDiskThroughput();
                    diskThrouthputTotal +=
                            Math.max(CnapCloudMgmtConstants.DISK_MAX_THROUGHPUT,nodeModel.getDiskThroughput());
                    diskIopsNow +=
                            nodeModel.getDiskIops();
                    diskIopsTotal +=
                            Math.max(CnapCloudMgmtConstants.DISK_MAX_IOPS,nodeModel.getDiskIops());

                    String flavorId = flavorMap.get(nodeModel.getNodeIp());
                    if(StringUtils.isNotEmpty(flavorId)) {
                        Double priceTmp = flavorInfoMapper.getPriceByFlavorId(flavorId);
                        if (priceTmp != null){
                            price += priceTmp;
                        }
                    }


                }
            }

            algClusterInfoV2Model.setCpuUse(cpuUse);
            algClusterInfoV2Model.setCpuTotal(cpuTotal);
            algClusterInfoV2Model.setMemUse(memUse);
            algClusterInfoV2Model.setMemTotal(memTotal);
            algClusterInfoV2Model.setDiskThroughputNow(diskThrouthputNow);
            algClusterInfoV2Model.setDiskThroughputTotal(diskThrouthputTotal);
            algClusterInfoV2Model.setDiskIopsNow(diskIopsNow);
            algClusterInfoV2Model.setDiskIopsTotal(diskIopsTotal);
            algClusterInfoV2Model.setPirce(price);

            //找到了对应的node才加信息
            if (addFlag) {
                algScheduleInfoV2Models.add(algClusterInfoV2Model);
            }
        }


        return algScheduleInfoV2Models;
    }

    @Override
    public List<AlgClusterInfoV2Model> getDeployAlgInfoV2(AlgReqModel algReqModel) throws Exception {

        List<AlgClusterInfoV2Model> algClusterInfoV2Models = new ArrayList<>();
        for (String k8sClusterName : algReqModel.getK8sClusterNames()) {

            K8sClusterBasicModel k8sClusterBasicModel
                    = multiCloudMgmtService.getK8sClusterInfoByName(k8sClusterName);
            List<NodeModel> nodeModels = k8sClusterService.getAllNodeInfo(k8sClusterBasicModel);
            AlgClusterInfoV2Model algClusterInfoV2Model = new AlgClusterInfoV2Model();
            algClusterInfoV2Model.setNodeNum(nodeModels.size());

            algClusterInfoV2Model.setK8sClusterName(k8sClusterBasicModel.getK8sClusterName());
            algClusterInfoV2Model.setRegionId(k8sClusterBasicModel.getRegionId());
            algClusterInfoV2Model.setZoneId(k8sClusterBasicModel.getZoneId());
            algClusterInfoV2Model.setCloudType(
                    CloudVendorsEnum.getCloudeTypeByDescribe(k8sClusterBasicModel.getCloudVendor()));
            algClusterInfoV2Model.setAccountName(k8sClusterBasicModel.getAccountName());
            algClusterInfoV2Model.setStatus(k8sClusterBasicModel.getK8sStatus());
            if (!StringUtils.equalsIgnoreCase(algClusterInfoV2Model.getStatus(),
                    K8sStatusEnum.Running.getChineseDescribe())){
                algClusterInfoV2Model.setStatus(K8sStatusEnum.Stop.getDescribe());
                algClusterInfoV2Models.add(algClusterInfoV2Model);
                continue;
            }else {
                algClusterInfoV2Model.setStatus(K8sStatusEnum.Running.getDescribe());

            }

            for (NodeModel nodeModel:nodeModels){
                //判断master节点能不能被使用
                if (StringUtils.equals(nodeModel.getNodeRole(),K8sRoleEnum.Master.getStatus())){

                    //master节点部署的是当前应用，或者master节点部署为空，都认为可用
                    if ((StringUtils.equals(nodeModel.getNodeLabelMap().get(CnapCloudMgmtConstants.NODE_APP_LABEL),
                                    CnapCloudMgmtConstants.NODE_APP_LABEL_EMPTY))
                            ||(StringUtils.equals(nodeModel.getNodeLabelMap().get(CnapCloudMgmtConstants.NODE_APP_LABEL),
                                algReqModel.getSvcName()))){

                        algClusterInfoV2Model.setMasterNodeAvailable(1);

                        //根据master ip找到master节点的ip
                        for (VmModel vmModel:k8sClusterBasicModel.getVmModels()){

                            if (StringUtils.equalsIgnoreCase(vmModel.getInnerIp(),nodeModel.getNodeIp())){

                                algClusterInfoV2Model.setMasterCpuNum(vmModel.getCpuNum());
                                algClusterInfoV2Model.setMasterMemByG(vmModel.getMemByG());
                                if (StringUtils.isNotEmpty(vmModel.getGpuFlavor())){
                                    String[] gpuFlavors = vmModel.getGpuFlavor().split("——");
                                    if (gpuFlavors.length == 2){
                                        algClusterInfoV2Model.setGpu(gpuFlavors[0]);
                                        algClusterInfoV2Model.setGpuMemorySize(gpuFlavors[1]);
                                    }
                                }
                                break;
                            }
                        }
                    }

                    algClusterInfoV2Model.setMasterCpuUse(
                            Double.parseDouble(QuantityUtils.changeCpuNtoNumStr(nodeModel.getNodeCpuUseByN())));
                    algClusterInfoV2Model.setMasterCpuTotal(
                            Double.parseDouble(QuantityUtils.changeCpuNtoNumStr(nodeModel.getNodeCpuQuotaByN())));
                    algClusterInfoV2Model.setMasterMemUse(
                            Double.parseDouble(QuantityUtils.changeMemKitoGiStr(nodeModel.getNodeMemUseNumByKi())));
                    algClusterInfoV2Model.setMasterMemTotal(
                            Double.parseDouble(QuantityUtils.changeMemKitoGiStr(nodeModel.getNodeMemQuotaByKi())));

                    if (StringUtils.equalsIgnoreCase(nodeModel.getNodeHardware(),CnapCloudMgmtConstants.ARCH_GPU)){
                        algClusterInfoV2Model.setGpuUse(nodeModel.getNodeGpuMemUse());
                        algClusterInfoV2Model.setGpuTotal(nodeModel.getNodeGpuMemTotal());
                    }
                }
            }

            //根据accountName去找网络情况
            String accountName = k8sClusterBasicModel.getAccountName();
            algClusterInfoV2Model.setLinkResInfoModel(
                    microSvcUseInfoMapper.getLinkResInfoRecentByName(accountName));

            algClusterInfoV2Models.add(algClusterInfoV2Model);
        }

        return algClusterInfoV2Models;
    }

    /**
     *
     * @param algReqModel
     * @return
     * @throws Exception
     */
    @Override
    public List<K8sClusterAlgInfoModel> getHpaAlgInfo(AlgReqModel algReqModel) throws Exception {

        List<K8sClusterAlgInfoModel> result = new ArrayList<>();
        for (String k8sClusterName : algReqModel.getK8sClusterNames()) {

            //过滤掉独立隔离的集群，因为他们不能被部署其他应用
            if (StringUtils.containsIgnoreCase(k8sClusterName,CnapCloudMgmtConstants.FORCED_ISOLATION)){
                continue;
            }

            K8sClusterBasicModel k8sClusterBasicModel
                    = multiCloudMgmtService.getK8sClusterInfoByName(k8sClusterName);

            if ((k8sClusterBasicModel == null) || (!StringUtils.equals(k8sClusterBasicModel.getK8sStatus(), K8sStatusEnum.Running.getChineseDescribe()))) {

                throw new Exception(k8sClusterName + "-集群状态异常状态异常");
            }
            
            K8sClusterAlgInfoModel k8sClusterAlgInfoModel = new K8sClusterAlgInfoModel();
            k8sClusterAlgInfoModel.setK8sClusterName(k8sClusterBasicModel.getK8sClusterName());
            k8sClusterAlgInfoModel.setK8sClusterIp(k8sClusterBasicModel.getK8sClusterIp());
            k8sClusterAlgInfoModel.setCreateUser(k8sClusterBasicModel.getCreateUser());
            k8sClusterAlgInfoModel.setClusterInfoJson(k8sClusterBasicModel.getClusterInfoJson());
            k8sClusterAlgInfoModel.setRegionId(k8sClusterBasicModel.getRegionId());
            k8sClusterAlgInfoModel.setZoneId(k8sClusterBasicModel.getZoneId());
            k8sClusterAlgInfoModel.setCloudType(CloudVendorsEnum.getCloudeTypeByDescribe(k8sClusterBasicModel.getCloudVendor()));
            k8sClusterAlgInfoModel.setCloudVendor(k8sClusterBasicModel.getCloudVendor());
            List<NodeModel> nodeModels = new ArrayList<>();

            if (StringUtils.isNotEmpty(algReqModel.getNodeAppType())) {
                nodeModels = k8sClusterService.getAllNodeInfo(k8sClusterBasicModel, null,
                        CnapCloudMgmtConstants.NODE_APP_TYPE_LABEL + algReqModel.getNodeAppType().toLowerCase(),
                        algReqModel.getNodeAppType().toLowerCase());

            }else if (StringUtils.isNotEmpty(algReqModel.getSvcName())) {

                nodeModels =k8sClusterService.getAllNodeInfo(k8sClusterBasicModel, null,
                        CnapCloudMgmtConstants.NODE_APP_LABEL,algReqModel.getSvcName());

            }else {

                nodeModels = k8sClusterService.getAllNodeInfo(k8sClusterBasicModel);
            }

            int cpuNum = 0;
            long cpuUseByN = 0L;

            long memQuotaByKi = 0L;
            long memUseByKi = 0L;

            int diskQuotaByGi = 0;
            int diskUseByGi = 0;

            int netCurrentBandWidth = 0;
            int netBandWidth = 0;

            double gpuUsage = 0;
            double gpuTemp = 0;
            double gpuMemUsage = 0;

            k8sClusterAlgInfoModel.setNodeNum(nodeModels.size());
            int gpuNodeNum = 0;
            for (NodeModel nodeModel:nodeModels){

                cpuNum += nodeModel.getNodeCpuQuota();
                cpuUseByN += nodeModel.getNodeCpuUseByN();

                memQuotaByKi += nodeModel.getNodeMemQuotaByKi();
                memUseByKi += nodeModel.getNodeMemUseNumByKi();

                diskQuotaByGi += nodeModel.getNodeDiskQuota();
                diskUseByGi += nodeModel.getNodeDiskUseNum();

                netCurrentBandWidth +=
                        (int)(prometheusService.getNodeNetBandwidthBybps(k8sClusterBasicModel.getK8sClusterIp(),
                                nodeModel.getNodeIp(),nodeModel.getArch()));
                netBandWidth += CnapCloudMgmtConstants.NODE_NET_BANDWIDTH;

                if (nodeModel.getNodeGpuTemp() > 0) {
                    gpuNodeNum++;
                    gpuUsage = gpuUsage + nodeModel.getNodeGpuUsage();
                    gpuTemp = gpuTemp + nodeModel.getNodeGpuTemp();
                    gpuMemUsage = gpuMemUsage + nodeModel.getNodeGpuMemUsage();
                }
            }

            k8sClusterAlgInfoModel.setClusterCpuNum(cpuNum);
            k8sClusterAlgInfoModel.setClusterCpuUseNum(Double.parseDouble(QuantityUtils.changeCpuNtoNumStr(cpuUseByN)));

            k8sClusterAlgInfoModel.setClusterMemUseByMb((int)(memUseByKi/1024));
            k8sClusterAlgInfoModel.setClusterMemQuotaByMb((int)(memQuotaByKi/1024));

            k8sClusterAlgInfoModel.setClusterDiskQuotaByGb(diskQuotaByGi);
            k8sClusterAlgInfoModel.setClusterDiskUseByGb(diskUseByGi);

            k8sClusterAlgInfoModel.setClusterNetCurrentBandwidth(netCurrentBandWidth / 1024 / 1024);
            k8sClusterAlgInfoModel.setClusterNetBandwidth(netBandWidth);

            k8sClusterAlgInfoModel.setNodeModels(nodeModels);

            if (gpuNodeNum > 0){
                k8sClusterAlgInfoModel.setGpuUsage(gpuUsage/gpuNodeNum);
                k8sClusterAlgInfoModel.setGpuMemUsage(gpuMemUsage/gpuNodeNum);
                k8sClusterAlgInfoModel.setGpuTemp(gpuTemp/gpuNodeNum);
            }

            result.add(k8sClusterAlgInfoModel);
            
        }

        return result;
    }

    /**
     *{
     *     "operation": "schedule",
     *     "policy": "load balancing",     //表示请求负载均衡的调度算法
     *     "service_name": "face_detection", //微服务名称
     *     "parameters":
     *      {
     *        "cluster_state":
     *                { //每个集群当前的状态，Dict格式，key为集群名称，value为具体资源值
     *          "cluster_name1":[ //list格式，每个部署了该应用的节点为一个元素
     *           [ //list格式，每个部署了该应用的节点下每个副本占用的资源情况为一个元素* 						{//cluster_name1下节点1下第一个副本的资源情况
     * 							"cpu_usage": [0.8, 4.0], //CPU使用状况, [该副本的cpu使用量,该副本cpu总量]，单位为核数
     * 							"memory_usage": [120, 12288], //内存使用状况,[该副本当前的内存使用量,该副本内存总量],单位为MB
     * 							"disk_throughput": [100, 1000], //磁盘吞吐量,[该副本当前的占用读写速率，该副本总读写速率]，单位为MB/s
     * 							"disk_iops": [1200, 15000], //磁盘IOPS，[该副本当前的占用读写次数，该副本秒均总读写次数]，单位次/s
     * 							"net_bandwidth": [1000, 100000], //网络带宽，[该副本当前的占用带宽，该副本网络总带宽]，单位bps
     * 							//注意：此处副本的资源总量为：若yaml中定义了副本最大资源量则用该值，若没有定义，则为该节点的总资源/该节点下所有应用的所有副本数量
     * 						},
     * 						{//cluster_name1下节点1下第2个副本的资源情况
     * 							...
     * 						},
     * 					],
     *           [//cluster_name1下节点2
     * 		      ...
     *             ]
     *           ],
     *          "cluster_name2":[
     * 		    ...//同上
     * 			]
     *         },
     *         "cluster_init_state":
     *   		  {//该应用部署后空载时每个副本的占用资源情况，部署后，对所有副本占用资源取平均
     *               "cpu_usage": 0.3, //CPU使用状况, 该副本当前cpu使用量，单位为核数
     *               "memory_usage": 120, //内存使用状况,该副本当前的内存使用量,单位为MB
     *               "disk_throughput": 50, //磁盘吞吐量,该副本当前该占用读写速率，单位为MB/s
     *               "disk_iops": 200, //磁盘IOPS，[该副本当前该应用的占用读写次数，单位次/s
     *               "net_bandwidth": 100, //网络带宽，[该副本当前该应用的占用带宽，单位bps
     *         },
     *        "request_resources_map": //该微服务应用的请求---消耗资源映射关系基准值
     *         {
     *               "cpu_usage": 0.3, //CPU使用状况, 每请求cpu使用量，单位为核数
     *               "memory_usage": 120, //内存使用状况,每请求的内存使用量,单位为MB
     *               "disk_throughput": 50, //磁盘吞吐量,每请求占用读写速率，单位为MB/s
     *               "disk_iops": 200, //磁盘IOPS，每请求占用读写次数，单位次/s
     *               "net_bandwidth": 100, //网络带宽，每请求占用带宽，单位bps
     *         }
     *         "num_under_processed_request":2000, //正在处理中的请求数量（周期统计、累加）
     *      }
     * }
     * @param algReqModel
     * @return
     * @throws Exception
     */
    @Override
    public List<NodeAlgInfoModel> getLoadBalaceDeployAlgInfo(AlgReqModel algReqModel) throws Exception {

        List<NodeAlgInfoModel> result = new ArrayList<>();
        for (String k8sClusterName : algReqModel.getK8sClusterNames()) {

            //过滤掉独立隔离的集群，因为他们不能被部署其他应用
            if (StringUtils.containsIgnoreCase(k8sClusterName,CnapCloudMgmtConstants.FORCED_ISOLATION)){
                continue;
            }

            K8sClusterBasicModel k8sClusterBasicModel
                    = multiCloudMgmtService.getK8sClusterInfoByName(k8sClusterName);

            if ((k8sClusterBasicModel == null) || (!StringUtils.equals(k8sClusterBasicModel.getK8sStatus(), K8sStatusEnum.Running.getChineseDescribe()))) {

                throw new Exception(k8sClusterName + "-集群状态异常状态异常");
            }

            LOGGER.info("getLoadBalaceDeployAlgInfo k8sCluserName={} appType={}",k8sClusterName,algReqModel.getNodeAppType());

            String labelKey = null;
            if (StringUtils.isNotEmpty(algReqModel.getNodeAppType())){
                labelKey = CnapCloudMgmtConstants.NODE_APP_TYPE_LABEL + algReqModel.getNodeAppType().toLowerCase();
            }

            List<NodeModel> nodeModels =
                    k8sClusterService.getAllNodeInfo(k8sClusterBasicModel,"",labelKey,algReqModel.getNodeAppType());

            LOGGER.info("getLoadBalaceDeployAlgInfo nodeModels.size={}",nodeModels.size());

            Long cpuUseByN = 0L;
            Long cpuNumByN = 0L;
            List<NodeAlgInfoModel> tmpResult = new ArrayList<>();
            for (NodeModel nodeModel : nodeModels) {

                LOGGER.info("getLoadBalaceDeployAlgInfo nodeModels name={}",nodeModel.getNodeName());

                NodeAlgInfoModel nodeAlgInfoModel = new NodeAlgInfoModel();
                nodeAlgInfoModel.setK8sClusterName(k8sClusterBasicModel.getK8sClusterName());
                nodeAlgInfoModel.setK8sClusterIp(k8sClusterBasicModel.getK8sClusterIp());
                nodeAlgInfoModel.setRegionId(k8sClusterBasicModel.getRegionId());
                nodeAlgInfoModel.setZoneId(k8sClusterBasicModel.getZoneId());
                nodeAlgInfoModel.setCloudType(CloudVendorsEnum.getCloudeTypeByDescribe(k8sClusterBasicModel.getCloudVendor()));
                nodeAlgInfoModel.setCloudVendor(k8sClusterBasicModel.getCloudVendor());
                nodeAlgInfoModel.setNodeName(nodeModel.getNodeName());
                nodeAlgInfoModel.setCreateUser(k8sClusterBasicModel.getCreateUser());
                nodeAlgInfoModel.setPodNum(nodeModel.getNodeContainerNormalNum());
                nodeAlgInfoModel.setCpuNum(nodeModel.getNodeCpuQuota());
                nodeAlgInfoModel.setCpuUseNumByN(nodeModel.getNodeCpuUseByN());
                cpuUseByN += nodeModel.getNodeCpuUseByN();
                cpuNumByN += nodeModel.getNodeCpuQuotaByN();
                nodeAlgInfoModel.setCpuUseNum(
                        Double.parseDouble(QuantityUtils.changeCpuNtoNumStr(nodeModel.getNodeCpuUseByN())));
                nodeAlgInfoModel.setMemQuato(
                        QuantityUtils.changeMemKitoMiNoMi(nodeModel.getNodeMemQuotaByKi()));
                nodeAlgInfoModel.setMemUse(
                        QuantityUtils.changeMemKitoMiNoMi(nodeModel.getNodeMemUseNumByKi()));

                nodeAlgInfoModel.setDiskCurrentThroughput(
                        (int) prometheusService.getNodeDiskThroughputByMbPerS(k8sClusterBasicModel.getK8sClusterIp(), nodeModel.getNodeIp(),
                        nodeAlgInfoModel.getArch()));
                nodeAlgInfoModel.setDiskThroughput(
                        Math.max(CnapCloudMgmtConstants.DISK_MAX_THROUGHPUT, nodeAlgInfoModel.getDiskCurrentThroughput()));
                nodeAlgInfoModel.setDiskCurrentIpos(
                        (int) prometheusService.getNodeDiskIOPS(k8sClusterBasicModel.getK8sClusterIp(), nodeModel.getNodeIp(),nodeAlgInfoModel.getArch()));
                nodeAlgInfoModel.setDiskIpos(
                        Math.max(CnapCloudMgmtConstants.DISK_MAX_IOPS, nodeAlgInfoModel.getDiskCurrentIpos()));
                nodeAlgInfoModel.setNetCurrentBandwidth(
                        (int) prometheusService.getNodeNetBandwidthBybps(k8sClusterBasicModel.getK8sClusterIp(),
                                nodeModel.getNodeIp(),nodeAlgInfoModel.getArch()) / 1024 / 1024);
                nodeAlgInfoModel.setNetBandwidth(
                        Math.max(CnapCloudMgmtConstants.NODE_NET_BANDWIDTH, nodeAlgInfoModel.getNetCurrentBandwidth()) / 1024 / 1024);
                nodeAlgInfoModel.setDelay(CnapCloudMgmtConstants.NET_DEALY);
                nodeAlgInfoModel.setLossRate(CnapCloudMgmtConstants.NET_LOSS_RATE);

                tmpResult.add(nodeAlgInfoModel);
            }

            //计算集群cpu平均使用
            double clusterCpuUsage =
                    Double.parseDouble(String.format("%.2f", ((cpuUseByN.doubleValue() / cpuNumByN.doubleValue()) * 100)));
            
            for (NodeAlgInfoModel nodeAlgInfoModel:tmpResult){

                nodeAlgInfoModel.setPidle(k8sClusterBasicModel.getPidle());
                nodeAlgInfoModel.setPmax(k8sClusterBasicModel.getPmax());
                nodeAlgInfoModel.setCpuUsage(clusterCpuUsage);
            }

            result.addAll(tmpResult);
        }

        return result;
    }

    /**
     *1、对cluster_init_state，计算每个集群、每个副本，空请求时的资源占用量，计算方法为取均值
     * 格式为{"cpu"：{"cluster1":0.02, "cluster2":0.5}, "memory":{"cluster1":1000, "cluster2": 200}, ..}
     * （由于部署时只部署1个副本，因此一个节点的资源占用即为一个副本的）
     *
     * 2、对resources_status，计算当前集群每种资源的用量：
     * 容器组 = 该集群下部署了这个应用的节点们
     * 资源用量 = 当前该容器组使用量 - 第一步中该集群每副本初始资源用量*当前该集群该应用的副本数
     * 副本数 = 该集群下容器组内所有节点上副本数之和
     * 资源余量 = 当前该容器组资源总量 - 当前该容器组资源已使用量
     * 当前该容器组资源总量 = 所有节点的所有副本资源总量加和
     * 当前该容器组资源已使用量 = 所有节点的所有副本已使用资源总量之和
     * 进而得到resources_status：
     * [      ["cpu", [ ["cluster1"],  1.23,3.22], [["cluster2"], 2.55, 1.02],  [["cluster3"], 3.77, 0.08], ... ]
     * [ [资源名，[ [集群名]， 集群内该应用的资源用量， 集群内资源剩余量],   [ [集群名]， 集群内该应用的资源用量， 集群内资源剩余量] ]
     * 调度最细粒度只考虑到集群，且认为集群资源不存在共享
     * 3、request_resources_map：第一次由测试组测试后提前预置，静态写入文件，直接读取即可；后续由上一次算法输出获取（写入文件/全局变量）
     * @param algReqModel
     * @return
     * @throws Exception
     */
    @Override
    public List<NodeAlgInfoModel> getLoadBalanceInvokeAlgInfo(AlgReqModel algReqModel) throws Exception {

        List<NodeAlgInfoModel> result = new ArrayList<>();

        List<NodeAlgInfoModel> nodeInfos = getLoadBalaceDeployAlgInfo(algReqModel);
        Map<String, NodeAlgInfoModel> nodeInfoMap = new HashMap<>();
        for (NodeAlgInfoModel nodeAlgInfoModel : nodeInfos) {
            nodeInfoMap.put(nodeAlgInfoModel.getNodeName() + nodeAlgInfoModel.getK8sClusterIp(), nodeAlgInfoModel);
        }

        for (String clusterName : algReqModel.getK8sClusterNames()) {
            K8sClusterBasicModel k8sClusterBasicModel
                    = multiCloudMgmtService.getK8sClusterInfoByName(clusterName);

            //获取namespace下所有的pod
            List<PodModel> podModelList
                    = k8sClusterService.getAllPodsInfo(k8sClusterBasicModel, algReqModel.getNamespace());
            for (PodModel podModel : podModelList) {

                if ((podModel.getWorkLoadModel() != null)
                        &&(StringUtils.equals(podModel.getWorkLoadModel().getWorkLoadName(),
                                            algReqModel.getWorkdLoadName()))) {

                    NodeAlgInfoModel nodeAlgInfoModel =
                            nodeInfoMap.get(podModel.getNodeName() + k8sClusterBasicModel.getK8sClusterIp());
                    if (nodeAlgInfoModel == null){
                        continue;
                    }

                    PodAlgInfoModel podAlgInfoModel = new PodAlgInfoModel();
                    podAlgInfoModel.setK8sClusterName(clusterName);
                    podAlgInfoModel.setK8sClusterIp(k8sClusterBasicModel.getK8sClusterIp());
                    podAlgInfoModel.setCpuUseNum(
                            Double.parseDouble(QuantityUtils.changeCpuNtoNumStr(podModel.getCpuUseByN())));

                    if (podModel.getPodLimitCpuByN() != 0) {

                        podAlgInfoModel.setCpuNum(
                                Double.parseDouble(QuantityUtils.changeCpuNtoNumStr(podModel.getPodLimitCpuByN())));

                    } else {

                        //没有限额的情况下，看看node情况
                        int podNum = nodeAlgInfoModel.getPodNum();
                        if (podNum == 0){
                            podNum = 1;
                        }
                        podAlgInfoModel.setCpuNum(
                                Math.max(podAlgInfoModel.getCpuNum(), nodeAlgInfoModel.getCpuNum() / podNum));
                    }

                    podAlgInfoModel.setMemUse(
                            QuantityUtils.changeMemKitoMiNoMi(podModel.getMemUseByKi()));
                    if (podModel.getPodLimitMemByKi() != 0) {
                        podAlgInfoModel.setMemQuato(
                                QuantityUtils.changeMemKitoMiNoMi(podModel.getMemUseByKi()));
                    } else {

                        int podNum = nodeAlgInfoModel.getPodNum();
                        if (podNum == 0){
                            podNum = 1;
                        }
                        podAlgInfoModel.setMemQuato(
                                Math.max(podAlgInfoModel.getMemUse(), nodeAlgInfoModel.getMemQuato() / podNum));
                    }

                    podAlgInfoModel.setDiskCurrentThroughput(nodeAlgInfoModel.getDiskCurrentThroughput());
                    podAlgInfoModel.setDiskThroughput(CnapCloudMgmtConstants.DISK_MAX_THROUGHPUT);

                    podAlgInfoModel.setDiskCurrentIpos(nodeAlgInfoModel.getDiskCurrentIpos());
                    podAlgInfoModel.setDiskIpos(CnapCloudMgmtConstants.DISK_MAX_IOPS);

                    podAlgInfoModel.setNetCurrentBandwidth(nodeAlgInfoModel.getNetCurrentBandwidth());
                    podAlgInfoModel.setNetBandwidth(nodeAlgInfoModel.getNetBandwidth());

                    if (nodeAlgInfoModel.getPodAlgInfoModels() == null) {
                        nodeAlgInfoModel.setPodAlgInfoModels(new ArrayList<>());
                    }

                    nodeAlgInfoModel.getPodAlgInfoModels().add(podAlgInfoModel);
                }
            }
        }


        for (NodeAlgInfoModel nodeAlgInfoModel : nodeInfoMap.values()) {
            if (nodeAlgInfoModel.getPodAlgInfoModels() != null) {
                result.add(nodeAlgInfoModel);
            }
        }

        if ((algReqModel.getInitStateFlag() != null)
                &&(algReqModel.getInitStateFlag())){

            PodAlgInfoModel resultPodAlgInfoModel = new PodAlgInfoModel();
            resultPodAlgInfoModel.setWorkLoadName(algReqModel.getWorkdLoadName());
            int podNum = 0;
            for (NodeAlgInfoModel nodeAlgInfoModel:result){
                for (PodAlgInfoModel podAlgInfoModel:nodeAlgInfoModel.getPodAlgInfoModels()){
                    resultPodAlgInfoModel.setCpuUseNum(resultPodAlgInfoModel.getCpuNum() + podAlgInfoModel.getCpuUseNum());
                    resultPodAlgInfoModel.setMemUse(resultPodAlgInfoModel.getMemUse() + podAlgInfoModel.getMemUse());
                    resultPodAlgInfoModel.setDiskCurrentThroughput(
                            resultPodAlgInfoModel.getDiskCurrentThroughput() + podAlgInfoModel.getDiskCurrentThroughput());
                    resultPodAlgInfoModel.setDiskCurrentIpos(
                            resultPodAlgInfoModel.getDiskCurrentIpos() + podAlgInfoModel.getDiskCurrentIpos());
                    resultPodAlgInfoModel.setNetCurrentBandwidth(
                            resultPodAlgInfoModel.getNetCurrentBandwidth() + podAlgInfoModel.getNetCurrentBandwidth());

                    podNum++;
                }
            }

            if (podNum != 0) {
                resultPodAlgInfoModel.setCpuUseNum(resultPodAlgInfoModel.getCpuNum() / podNum);
                resultPodAlgInfoModel.setMemUse(resultPodAlgInfoModel.getMemUse() / podNum);
                resultPodAlgInfoModel.setDiskCurrentThroughput(
                        resultPodAlgInfoModel.getDiskCurrentThroughput() / podNum);
                resultPodAlgInfoModel.setDiskCurrentIpos(
                        resultPodAlgInfoModel.getDiskCurrentIpos() / podNum);
                resultPodAlgInfoModel.setNetCurrentBandwidth(
                        resultPodAlgInfoModel.getNetCurrentBandwidth() / podNum);
            }


            NodeAlgInfoModel resultNodeAlgInfoModel = new NodeAlgInfoModel();
            resultNodeAlgInfoModel.setInitPodAlgInfoModel(resultPodAlgInfoModel);
            result.clear();
            result.add(resultNodeAlgInfoModel);
        }
  
        return result;
    }

    @Override
    public List<GpuClusterMonitorInfo> getTop5GpuClusterInfo() {

        List<GpuClusterMonitorInfo> result = new ArrayList<>();

        //用于排序
        List<GpuClusterMonitorInfo> tmpResult = new ArrayList<>();


        //获取所有gpu集群
        List<K8sClusterBasicModel> k8sClusterBasicModels =
                multiCloudMgmtService.getAllGpuInUseClusterInfos();
        //去获取gpu的信息
        for (K8sClusterBasicModel k8sClusterBasicModel:k8sClusterBasicModels){

            GpuClusterMonitorInfo gpuClusterMonitorInfo = new GpuClusterMonitorInfo();
            gpuClusterMonitorInfo.setCloudType(
                    CloudVendorsEnum.getCloudeTypeByDescribe(k8sClusterBasicModel.getCloudVendor()));
            gpuClusterMonitorInfo.setClusterName(k8sClusterBasicModel.getK8sClusterName());
            tmpResult.add(gpuClusterMonitorInfo);

            try {
                List<NodeModel> nodeModels = k8sClusterService.getAllNodeInfo(k8sClusterBasicModel);
                if ((nodeModels == null)||(nodeModels.isEmpty())){
                    continue;
                }
                for (NodeModel nodeModel:nodeModels){
                    gpuClusterMonitorInfo.setGpuMemUsage(
                            gpuClusterMonitorInfo.getGpuMemUsage() + nodeModel.getNodeGpuMemUsage());
                    gpuClusterMonitorInfo.setGpuUsage(
                            gpuClusterMonitorInfo.getGpuUsage()+ nodeModel.getNodeGpuUsage());
                    gpuClusterMonitorInfo.setGpuClusterDisk(
                            nodeModel.getNodeDiskUseNum() + gpuClusterMonitorInfo.getGpuClusterDisk()
                    );
                    gpuClusterMonitorInfo.setGpuPodNum(
                            nodeModel.getPodModels().size() + gpuClusterMonitorInfo.getGpuPodNum());
                }
                gpuClusterMonitorInfo.setGpuMemUsage(
                        gpuClusterMonitorInfo.getGpuMemUsage()/nodeModels.size());
                gpuClusterMonitorInfo.setGpuUsage(
                        gpuClusterMonitorInfo.getGpuUsage()/nodeModels.size());

            }catch (Exception e){
                LOGGER.error("getTop5GpuClusterInfo get nodeInfo failed ip={}",
                        k8sClusterBasicModel.getK8sClusterIp(),e);
            }
        }

        tmpResult.sort((gpuClusterMonitorInfo, t1) -> (gpuClusterMonitorInfo.getGpuUsage() - t1.getGpuUsage())> 0?1:0);

        if (tmpResult.size() <= 5){
            result = tmpResult;

        }else {

           result = tmpResult.subList(0,5);
        }
        return result;
    }

    @Override
    public Map<String, Integer> getAccountNodeNum(List<AccountNameReqModel> accountNameReqModels) {
        Map<String, Integer> result = new HashMap<>();

        for (AccountNameReqModel accountNameReqModel:accountNameReqModels){
            result.put(accountNameReqModel.getAccountName(),0);
        }

        List<K8sClusterModel> k8sClusterModels = k8sClusterInfoMapper.getAllK8sClusterByClouderVendor(null);
        if (!k8sClusterModels.isEmpty()){
            for (K8sClusterModel k8sClusterModel:k8sClusterModels){
                if(StringUtils.isNotBlank(k8sClusterModel.getAccountName())
                    &&(k8sClusterModel.getVmModels() != null)
                    &&(!k8sClusterModel.getVmModels().isEmpty())){

                    if (result.containsKey(k8sClusterModel.getAccountName())){
                        result.put(k8sClusterModel.getAccountName(),
                                result.get(k8sClusterModel.getAccountName()) + k8sClusterModel.getVmModels().size());
                    }
                }
            }
        }

        return result;
    }
}
